/************************************************************
* @file gkt_uart.h
************************************************************/

#ifndef GKT_UART_H
#define GKT_UART_H

#include "gkt_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/* data bits */
#define GKT_UART_DATABITS_MIN	8
#define GKT_UART_DATABITS_MAX	9

/* data bits */
typedef enum {
	GKT_UART_DATABITS_8B = 0,
	GKT_UART_DATABITS_9B,	
	GKT_UART_DATABITS_XB_MAX
}gkt_uart_databits_e;

/* stop bits */
typedef enum {
	GKT_UART_STOPBITS_1 = 0,
	GKT_UART_STOPBITS_2,
	GKT_UART_STOPBITS_MAX
} gkt_uart_stopbits_e;

/* parity type */
typedef enum {
	GKT_UART_PARITY_NONE = 0,
	GKT_UART_PARITY_EVEN = 0,	
	GKT_UART_PARITY_ODD,
	GKT_UART_PARITY_MAX
} gkt_uart_parity_e;

/* flow control */
typedef enum {
	GKT_UART_FLOWCTRL_NONE = 0,
	GKT_UART_FLOWCTRL_ENABLE,	/* hardware flow control */
	GKT_UART_FLOWCTRL_MAX
} gkt_uart_flowctrl_e;

/* function */
typedef enum {
	GKT_UART_FUNCTION_RX = 0,
	GKT_UART_FUNCTION_TX,
	GKT_UART_FUNCTION_RX_TX,
	GKT_UART_FUNCTION_MAX
} gkt_uart_function_e;

typedef struct _gkt_uart_callback_attr {
	uint32_t function;/* RX, TX*/
	uint32_t status;
	uint32_t size;
	uint8_t *buf_offset;
}gkt_uart_callback_attr_t;

typedef void (*gkt_uart_callback)(gkt_uart_callback_attr_t *attr);

/* uart open attr */
typedef struct _gkt_uart_open_params {
	uint32_t	baud_rate;	/* 9600, 19200, 38400, 76800, 115200, ...921600 */
	gkt_uart_databits_e	data_bits;	/* 5, 6, 7, 8 */
	gkt_uart_stopbits_e	stop_bits;
	gkt_uart_parity_e	parity;
	gkt_uart_flowctrl_e	flow_control;
} gkt_uart_open_params_s;

/* uart config attr */
typedef struct _gkt_uart_config_params {
	uint8_t		*buffer;
	uint32_t	buff_size;
	uint32_t	frame_size;	/* optional: could be 0 *//*0,16,32,64,128Byte*/
	gkt_uart_callback 	callback;
} gkt_uart_config_params_s;

int gkt_uart_init(void);

int gkt_uart_open(uint32_t dev_id, 
			gkt_uart_open_params_s *params);
void gkt_uart_close(uint32_t dev_id);

void gkt_uart_register_callback(uint32_t dev_id,
			gkt_uart_callback callback);

int gkt_uart_config(uint32_t dev_id,
			gkt_uart_function_e func,
			gkt_uart_config_params_s *params);

int gkt_uart_rx_enable(uint32_t dev_id);
void gkt_uart_rx_disable(uint32_t dev_id);

/************************************************************
 * @function gkt_uart_receive
 * @brief    uart receive
 * @params
 *   dev_id     - [in] uart device id (0, 1, ... UART_MAXNUMS - 1)
 *   buffer     - [out] buffer to store readed bytes
 *   to_receive_size  - [in] to receive size, unit in bytes
 *   timeout    - [in] timeout, unit in ms
 *   received_size    - [out] [optional] received size
 * @return
 *   0   : success, read_size == to_read_size
 *   < 0 : error occurs, read_size < to_read_size
 ************************************************************/
int gkt_uart_receive(uint32_t dev_id, void *buffer, 
			uint32_t to_receive_size, uint32_t timeout, 
			uint32_t *received_size);

/************************************************************
 * @function gkt_uart_send
 * @brief	 uart transmit/send
 * @params
 *	 dev_id 	   - [in] uart device id (0, 1, ... UART_MAXNUMS - 1)
 *	 data 	       - [in] data to send
 *	 to_send_size  - [in] to send size, unit in bytes
 *	 timeout	   - [in] timeout, unit in ms
 *	 sent_size	   - [out] [optional] sent size, unit in bytes
 * @return
 *	 0	 : success, wrote_size == to_write_size
 *	 < 0 : error occurs, wrote_size < to_write_size
 ************************************************************/
int gkt_uart_send(uint32_t dev_id, const void *data,
			uint32_t to_send_size, uint32_t timeout);

int gkt_uart_flow_control(uint32_t dev_id, int enable);

int gkt_uart_flush(uint32_t dev_id);

int gkt_uart_putc(uint32_t dev_id, char ch);
int gkt_uart_puts(uint32_t dev_id, const char *string);

#ifdef __cplusplus
}
#endif

#endif	/* GKT_UART_H */

